package com.bootdo.netty.test;

import com.bootdo.netty.common.SmartCarDecoder;
import com.bootdo.netty.common.SmartCarEncoder;
import com.bootdo.netty.hander.ClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class Client {

    // 配置客户端NIO线程组
    EventLoopGroup group = new NioEventLoopGroup();
    // 客户端辅助启动类 对客户端配置
    Bootstrap b = new Bootstrap();
    public Client(){
        b.group(group)//
                .channel(NioSocketChannel.class)//
                .option(ChannelOption.TCP_NODELAY, true)//
                .handler(new MyChannelHandler());//
    }


    /**
     * 连接服务器
     *
     * @param port
     * @param host
     * @throws Exception
     */
    public void connect(int port, String host) throws Exception {

        try {


            // 异步链接服务器 同步等待链接成功
            ChannelFuture f = b.connect(host, port).addListener(new  ChannelFutureListener(){

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(future.isSuccess()){
                        System.out.println("连接成功...");
                    }else{
                        System.out.println("连接失败...");
                        restart();
                    }
                }
            });
            // 等待链接关闭
            f.channel().closeFuture().sync();

        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            System.out.println("客户端关闭了...");
            restart();
        }

    }

    public void restart() throws Exception {
        Thread.sleep(5000);
        System.out.println("重新连接...");
        connect(9999, "127.0.0.1");
    }

    /**
     * 网络事件处理器
     */
    private class MyChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            // 添加自定义协议的编解码工具
            ch.pipeline().addLast(new SmartCarEncoder());
            ch.pipeline().addLast(new SmartCarDecoder());
            // 处理网络IO
            ch.pipeline().addLast(new ClientHandler());
        }

    }

    public static void main(String[] args) throws Exception {
        new Client().connect(9999, "127.0.0.1");
    }

}
